package com.mxx.common.data.jpa;

import javax.persistence.criteria.*;

public abstract class AbstractUpdateSpecHelper<E extends AbstractUpdateSpecHelper<E, K>, K> extends AbstractSpecHelper<E, K> {
    protected CriteriaUpdate criteriaUpdate;
    protected int updateFieldNumber = 0;
    protected boolean allowNullCondition = false;

    protected AbstractUpdateSpecHelper(Root root, CriteriaBuilder criteriaBuilder, CriteriaQuery criteriaQuery, CriteriaUpdate criteriaUpdate) {
        super(root, criteriaBuilder, criteriaQuery);
        this.criteriaUpdate = criteriaUpdate;
    }

    public E set(K k, Object val) {
        criteriaUpdate.set(get(k), val);
        this.updateFieldNumber++;
        return getTarget();
    }

    public E sum(K k, Number val) {
        Expression<Number> expression = criteriaBuilder.sum(get(k), val);
        criteriaUpdate.set((Path<Number>) get(k), expression);
        this.updateFieldNumber++;
        return getTarget();
    }

    public E diff(K k, Number val) {
        Expression<Number> expression = criteriaBuilder.diff(get(k), val);
        criteriaUpdate.set((Path<Number>) get(k), expression);
        this.updateFieldNumber++;
        return getTarget();
    }

    /**
     * 商 （除法）
     *
     * @param k
     * @param val
     * @return
     */
    public E quot(K k, Number val) {
        Expression<Number> expression = criteriaBuilder.quot(get(k), val);
        criteriaUpdate.set((Path<Number>) get(k), expression);
        this.updateFieldNumber++;
        return getTarget();
    }

    /**
     * 取模
     *
     * @param k
     * @param val
     * @return
     */
    public E mod(K k, Integer val) {
        Expression<Number> expression = criteriaBuilder.mod(get(k), val);
        criteriaUpdate.set((Path<Number>) get(k), expression);
        this.updateFieldNumber++;
        return getTarget();
    }



    public E allowNullCondition() {
        this.allowNullCondition = true;
        return getTarget();
    }

    public UpdateSpecification.Result updateEndAnd() {
        Predicate predicate = this.endAnd();
        return new UpdateSpecification.Result(allowNullCondition, updateFieldNumber, predicate);
    }

    public UpdateSpecification.Result updateEndOr() {
        Predicate predicate = this.endOr();
        return new UpdateSpecification.Result(allowNullCondition, updateFieldNumber, predicate);
    }
}
